-
Notifications
You must be signed in to change notification settings - Fork 7
feat(logging): GoogleSdkLoggerDelegator initial implementation #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
These two pull requests introduce a standardized and dynamically configurable debug logging framework for Google Cloud Ruby clients and implement it in the Pub/Sub library. The primary goal was to enable on-demand debug logging that could be controlled by the developer via configuring a custom logger and controlling an environment variable to turn logs on/off. This required passing a logger from the handwritten client (google-cloud-pubsub) down to the underlying GAPIC client (google-cloud-pubsub-v1). I needed to build a wrapper around the logger (creating a logger duck-type) that will evaluate the environment variable before emitting logs. The Solution:
Once the first 2 PRs are approved, I will create a new PR that passes the GoogleSdkLoggerDelegator down to the GAPIC layer (google-cloud-pubsub-v1). |
viacheslav-rostovtsev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this approach is fine. A reasonable alternative would be to require a wrapped logger to handle its errors (like Logger does) and trust that whatever errors are going to be raised from the underlying logger are the errors that the end-user wants to see.
| # A delegator that wraps a logger or its duck-type instance to add dynamic | ||
| # filtering based on GOOGLE_SDK_RUBY_LOGGING_GEMS environment variable, and | ||
| # error supression based on suppress_logger_errors parameter | ||
| class GoogleSdkLoggerDelegator < SimpleDelegator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider calling it "Proxy" or "Wrapper" instead of "Delegator".
| class GoogleSdkLoggerDelegator < SimpleDelegator | ||
| # @private | ||
| # The environment variable that controls which gems have logging enabled. | ||
| ENV_VAR = "GOOGLE_SDK_RUBY_LOGGING_GEMS".freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"LOGGING_GEMS_ENV_VAR"
| suppress_errors { super } | ||
| end | ||
|
|
||
| def debug message = nil, &block |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it's Ruby 3.1 we can probably drop the block variable name and just use &
|
|
||
| # Return the cached result if the ENV var hasn't changed. | ||
| if @cached_env_var_value == current_env_var | ||
| return @cached_logging_enabled_result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cached instance-level variables should be explicitly initialized in the constructor.
| def is_logger_type? logger | ||
| return false if logger.nil? | ||
| REQUIRED_LOGGER_METHODS.all? { |m| logger.respond_to? m } | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a class-level (static) method
|
|
||
| def << msg | ||
| return true unless logging_enabled? | ||
| suppress_errors { super } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something like handle_logging_errors would be a better name, similar to handle_writing_errors in Logger's LogDevice
| # @param gem_name [String] The name of the gem this logger is for. | ||
| # @param logger [Logger] The custom logger instance to wrap. | ||
| # @param suppress_logger_errors [Boolean] Whether to swallow exceptions in the wrapped logger. | ||
| def initialize gem_name, logger, suppress_logger_errors: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should make it same as Logger by giving it a list of Errors to reraise instead of a blanket variable.
| require "google/logging/message" | ||
| require "google/logging/source_location" | ||
| require "google/logging/structured_formatter" | ||
| require "google/logging/google_sdk_filtered_logger" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
A delegator that wraps a logger or its duck-type instance to add dynamic filtering based on GOOGLE_SDK_RUBY_LOGGING_GEMS environment variable, and error supression based on suppress_logger_errors parameter. To be used for client library & GAPIC layer logging.